package main

import "fmt"

type treeNode struct {
	value       int
	left, right *treeNode
}

func (node treeNode) print() { // node 接收者
	fmt.Print(node.value, " ")
}

//func (node treeNode) setValue(value int) { // 值传递
//	node.value = value
//}

func (node *treeNode) setValue(value int) { // 指针接收者
	if node == nil {
		fmt.Println("Setting value to nil node. Ignored.")
		return
	}
	node.value = value
}

func (node *treeNode) traverse() {
	if node == nil {
		return
	}

	node.left.traverse() // 不用判断left是否为空，nil指针也可以调用方法
	node.print()
	node.right.traverse()
}

// 工厂函数
func createNode(value int) *treeNode {
	return &treeNode{value: value} // go语言可以返回局部变量地址给外部用，有垃圾回收机制
}

func main() {
	var root treeNode
	fmt.Println(root)

	root = treeNode{value: 3}
	root.left = &treeNode{}
	root.right = &treeNode{5, nil, nil}
	root.right.left = new(treeNode)
	root.left.right = createNode(2)
	fmt.Println(root)

	nodes := []treeNode{
		{value: 3},
		{},
		{6, nil, &root},
	}
	fmt.Println(nodes)

	root.print()
	fmt.Println()
	root.right.left.setValue(4) // 虽然是指针接收者，写法不用取地址
	root.right.left.print()
	fmt.Println()

	root.print()
	root.setValue(100)

	pRoot := &root
	pRoot.print()
	pRoot.setValue(200)
	pRoot.print()
	fmt.Println()

	var pRoot2 *treeNode
	pRoot2.setValue(200)

	root.traverse()
}
